/**
 *   sci4j - Java library for scientific computation.
 *
 *   Copyright (C) 2010 Inaki Ortiz de Landaluce
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package org.sci4j.imaging.plugins.dicom;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Iterator;

import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;

import org.sci4j.imaging.utils.ByteUtils;
import org.sci4j.imaging.utils.StringUtils;

public class DICOMImageReader extends ImageReader {

	private ImageInputStream stream;
	
	private boolean gotHeader = false;
	
	/**
	 * @param originatingProvider
	 */
	public DICOMImageReader(ImageReaderSpi originatingProvider) {
		super(originatingProvider);
	}

	/* 
	 * @see javax.imageio.ImageReader#getHeight(int)
	 */
	@Override
	public int getHeight(int imageIndex) throws IOException {
		return 0;
	}

	/* 
	 * @see javax.imageio.ImageReader#getImageMetadata(int)
	 */
	@Override
	public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
		return null;
	}

	/* 
	 * @see javax.imageio.ImageReader#getImageTypes(int)
	 */
	@Override
	public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex)
			throws IOException {
		return null;
	}

	/* 
	 * @see javax.imageio.ImageReader#getNumImages(boolean)
	 */
	@Override
	public int getNumImages(boolean allowSearch) throws IOException {
		return 0;
	}

	/* 
	 * @see javax.imageio.ImageReader#getStreamMetadata()
	 */
	@Override
	public IIOMetadata getStreamMetadata() throws IOException {
		return null;
	}

	/* 
	 * @see javax.imageio.ImageReader#getWidth(int)
	 */
	@Override
	public int getWidth(int imageIndex) throws IOException {
		return 0;
	}

	/* 
	 * @see javax.imageio.ImageReader#read(int, javax.imageio.ImageReadParam)
	 */
	@Override
	public BufferedImage read(int imageIndex, ImageReadParam param)
			throws IOException {
		readHeader();
		return null;
	}
	
	/* 
	 * @see javax.imageio.ImageReader#setInput(Object, boolean, boolean)
	 */	
	@Override
    public void setInput(Object input, boolean seekForwardOnly,
            boolean ignoreMetadata) {
        super.setInput(input, seekForwardOnly, ignoreMetadata);
        if(input != null) {
            if(input instanceof ImageInputStream) {
            	this.stream = (ImageInputStream)input;
            } else {
                throw new IllegalArgumentException(
                        "Input is not an ImageInputStream!");
            }
        }
    }	
	
	public void readHeader() throws IOException {
		if(this.gotHeader) {
			return;
		}
		this.gotHeader = true;
		
		if(this.stream == null) {
			throw new IllegalStateException("No input stream");
		}
		// PS3.10-2009, Section 7.1
		// The DICOM File Meta information consists of a fixed 128-byte 
		// field, followed by a 4-byte DICOM prefix containing
		// the character string "DICOM" plus a set of DICOM Meta Elements.
		byte[] b = new byte[132];
		try {			
			stream.readFully(b);			
		} catch(IOException e) {
			throw new IOException("Error reading signature", e);
		}		
		if(b[128] != (byte)'D' || b[129] != (byte)'I'
		   || b[130] != (byte)'C' || b[131] != (byte)'M') {
			throw new IOException("Bad file signature");
		}
		stream.mark();		
		// PS 3.10-2009 Table 7.7.1 DICOM File Meta Information
		// PS 3.5-2009 Table 6.2.1 DICOM Value Representations
		// File Meta Information Group Length: VR is UL i.e. 4 bytes fixed
		b = new byte[2];
		stream.readFully(b, 0, 2);
		System.out.println("File Meta Information Group length VR " + StringUtils.decode(b, "ISO-8859-1"));
		b = new byte[4];
		stream.readFully(b, 0, 4);
		System.out.println("File Meta Information Group length (Big endian) " + ByteUtils.bytesBE2int(b, 0));
		System.out.println("File Meta Information Group length (Little Endian) " + ByteUtils.bytesLE2int(b, 0));
		// File Meta Information Version: a two byte field with OB VR
		b = new byte[2];
		stream.readFully(b, 0, 2);
		System.out.println("File Meta Information Version VR " + StringUtils.decode(b, "ISO-8859-1"));
		b = new byte[4];
		stream.readFully(b, 0, 4);		
		System.out.println("File Meta Information Version (BE) " + ByteUtils.bytesBE2int(b, 0));
		System.out.println("File Meta Information Version (LE) " + ByteUtils.bytesLE2int(b, 0));
	}

}